home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr49 / 295_01.zip / BUOPS.C < prev    next >
Text File  |  1993-04-22  |  14KB  |  565 lines

  1. /*    Copyright (c) 1989 Citadel    */
  2. /*       All Rights Reserved        */
  3.  
  4. /* #ident    "buops.c    1.2 - 89/10/31" */
  5.  
  6. #include "blkio_.h"
  7.  
  8. /* check host definition */
  9. #ifndef HOST
  10. /*#error HOST macro not defined.*/
  11. #endif
  12. #if HOST != UNIX && HOST != MSDOS
  13. /*#error Invalid HOST macro definition.*/
  14. #endif
  15.  
  16. #include <errno.h>
  17. #if HOST == UNIX
  18. #include <fcntl.h>    /* open() macro definitions */
  19. #include <unistd.h>    /* lseek() macro definitions */
  20. int close(/*int fd*/);    /* system call declarations */
  21. long lseek(/*int fd, long offset, int whence*/);
  22. int open(/*char *path, int flags, ...*/);
  23. int read(/*int fd, char *buf, unsigned n*/);
  24. int write(/*int fd, char *buf, unsigned n*/);
  25. #define MODE    (0666)    /* file permissions for new files */
  26. #elif HOST == MSDOS
  27. #if MSDOSC == TURBOC
  28. #include <fcntl.h>    /* open() macro definitions */
  29. #include <io.h>        /* system call declarations, lseek() macro defs */
  30. #define MODE    (0x100 | 0x080)        /* file permissions for new files */
  31. #elif MSDOSC == MSC
  32. #include <fcntl.h>    /* open() macro definitions */
  33. #include <io.h>        /* system call declarations, lseek() macro defs */
  34. #define MODE    (0x100 | 0x080)        /* file permissions for new files */
  35. #elif MSDOSC == MSQC
  36. #include <fcntl.h>    /* open() macro definitions */
  37. #include <io.h>        /* system call declarations, lseek() macro defs */
  38. #define MODE    (0x100 | 0x080)        /* file permissions for new files */
  39. #endif    /* #if MSDOSC == TURBOC */
  40. #endif    /* #if HOST == MSDOS */
  41.  
  42. /*man---------------------------------------------------------------------------
  43. NAME
  44.      b_uclose - unbuffered close block file
  45.  
  46. SYNOPSIS
  47.      #include "blkio_.h"
  48.  
  49.      int b_uclose(bp)
  50.      BLKFILE *bp;
  51.  
  52. DESCRIPTION
  53.      The b_uclose function closes the file associated with the BLKFILE
  54.      pointer bp.
  55.  
  56.      b_uclose will fail if one or more of the following is true:
  57.  
  58.      [EINVAL]       bp is not a valid BLKFILE pointer.
  59.      [BENOPEN]      bp is not open.
  60.  
  61. SEE ALSO
  62.      b_uopen.
  63.  
  64. DIAGNOSTICS
  65.      Upon successful completion, a value of 0 is returned.  Otherwise,
  66.      a value of -1 is returned, and errno set to indicate the error.
  67.  
  68. ------------------------------------------------------------------------------*/
  69. int b_uclose(bp)
  70. BLKFILE *bp;
  71. {
  72. #ifdef DEBUG
  73.     /* validate arguments */
  74.     if (!b_valid(bp)) {
  75.         BEPRINT;
  76.         errno = EINVAL;
  77.         return -1;
  78.     }
  79.  
  80.     /* check if not open */
  81.     if (!(bp->flags & BIOOPEN)) {
  82.         BEPRINT;
  83.         errno = BENOPEN;
  84.         return -1;
  85.     }
  86. #endif
  87.  
  88.     /* close file */
  89. #if HOST == UNIX
  90.     if (close(bp->fd.ifd) == -1) {
  91.         BEPRINT;
  92.         return -1;
  93.     }
  94. #elif HOST == MSDOS
  95.     if (close(bp->fd.ifd) == -1) {
  96.         BEPRINT;
  97.         return -1;
  98.     }
  99. #endif
  100.  
  101.     errno = 0;
  102.     return 0;
  103. }
  104.  
  105. /*man---------------------------------------------------------------------------
  106. NAME
  107.      b_uendblk - unbuffered find end block
  108.  
  109. SYNOPSIS
  110.      #include "blkio_.h"
  111.  
  112.      int b_uendblk(bp, endblk_p)
  113.      BLKFILE *bp;
  114.      bpos_t *endblk_p;
  115.  
  116. DESCRIPTION
  117.      The b_uendblk function finds the block number of the first block
  118.      past the end of file of the file associated with BLKFILE pointer
  119.      bp.  This value is returned in the storage location pointed to by
  120.      endblk_p.  Blocks in buffer storage and not yet written to the
  121.      file are not counted, so this function should normally be used
  122.      when the file is first opened or preceded by a call to bsync.
  123.  
  124.      If the file does not end on a block boundary, the result is the
  125.      same as if the partial block (or header) at the end of the file
  126.      did not exist.
  127.  
  128.      b_uendblk will fail if one or more of the following is true:
  129.  
  130.      [EINVAL]       bp is not a valid BLKFILE pointer.
  131.      [BENOPEN]      bp is not open.
  132.  
  133. DIAGNOSTICS
  134.      Upon successful completion, a value of 0 is returned.  Otherwise,
  135.      a value of -1 is returned, and errno set to indicate the error.
  136.  
  137. ------------------------------------------------------------------------------*/
  138. int b_uendblk(bp, endblk_p)
  139. BLKFILE *bp;
  140. bpos_t *endblk_p;
  141. {
  142. #if HOST == UNIX
  143.     long pos = 0;
  144. #elif HOST == MSDOS
  145.     long pos = 0;
  146. #endif
  147.  
  148. #ifdef DEBUG
  149.     /* validate arguments */
  150.     if (!b_valid(bp)) {
  151.         BEPRINT;
  152.         errno = EINVAL;
  153.         return -1;
  154.     }
  155.  
  156.     /* check if not open */
  157.     if (!(bp->flags & BIOOPEN)) {
  158.         BEPRINT;
  159.         errno = BENOPEN;
  160.         return -1;
  161.     }
  162. #endif
  163.  
  164. #if HOST == UNIX || HOST == MSDOS
  165.     /* find position of end of file */
  166.     pos = lseek(bp->fd.ifd, (long)0, SEEK_END);
  167.     if (pos == -1) {
  168.         BEPRINT;
  169.         return -1;
  170.     }
  171.  
  172.     /* check if empty file (or incomplete header) */
  173.     if (pos < bp->hdrsize) {
  174.         *endblk_p = 0;
  175.         errno = 0;
  176.         return 0;
  177.     }
  178.  
  179.     /* find length past end of header */
  180.     pos -= bp->hdrsize;
  181.  
  182.     /* set return argument */
  183.     *endblk_p = (pos / bp->blksize) + 1;
  184. #endif
  185.  
  186.     errno = 0;
  187.     return 0;
  188. }
  189.  
  190. /*man---------------------------------------------------------------------------
  191. NAME
  192.      b_ugetf - unbuffered get field from block file
  193.  
  194. SYNOPSIS
  195.      #include "blkio_.h"
  196.  
  197.      int b_ugetf(bp, bn, offset, buf, bufsize)
  198.      BLKFILE *bp;
  199.      bpos_t bn;
  200.      size_t offset;
  201.      void *buf;
  202.      size_t bufsize;
  203.  
  204. DESCRIPTION
  205.      The b_ugetf function reads bufsize characters from block number
  206.      bn of the block file associated with BLKFILE pointer bp into the
  207.      buffer pointed to by buf.  A value of 0 for bn indicates the file
  208.      header.  The read starts offset characters from the beginning of
  209.      the block.  The sum of the offset and the bufsize must not exceed
  210.      the header size if bn is equal to zero, or the block size if bn
  211.      is not equal to zero.
  212.  
  213.      b_ugetf will fail if one or more of the following is true:
  214.  
  215.      [EINVAL]       bp is not a valid BLKFILE pointer.
  216.      [EINVAL]       buf is NULL.
  217.      [EINVAL]       bufsize is less than 1.
  218.      [BEBOUND]      offset + bufsize extends across a block
  219.                     boundary.
  220.      [BEEOF]        Block bn is past the end of file.
  221.      [BEEOF]        End of file encountered within block bn.
  222.      [BENOPEN]      bp is not open.
  223.  
  224. SEE ALSO
  225.      b_uputf.
  226.  
  227. DIAGNOSTICS
  228.      Upon successful completion, a value of 0 is returned.  Otherwise,
  229.      a value of -1 is returned, and errno set to indicate the error.
  230.  
  231. ------------------------------------------------------------------------------*/
  232. int b_ugetf(bp, bn, offset, buf, bufsize)
  233. BLKFILE *bp;
  234. bpos_t bn;
  235. size_t offset;
  236. void *buf;
  237. size_t bufsize;
  238. {
  239. #if HOST == UNIX
  240.     long pos = 0;
  241.     int nr = 0;
  242. #elif HOST == MSDOS
  243.     long pos = 0;
  244.     int nr = 0;
  245. #endif
  246.  
  247. #ifdef DEBUG
  248.     /* validate arguments */
  249.     if (!b_valid(bp) || (buf == NULL) || (bufsize < 1)) {
  250.         BEPRINT;
  251.         errno = EINVAL;
  252.         return -1;
  253.     }
  254.  
  255.     /* check if not open */
  256.     if (!(bp->flags & BIOOPEN)) {
  257.         BEPRINT;
  258.         errno = BENOPEN;
  259.         return -1;
  260.     }
  261.  
  262.     /* check if block boundary is crossed */
  263.     if (bn == 0) {
  264.         if ((offset + bufsize) > bp->hdrsize) {
  265.             BEPRINT;
  266.             errno = BEBOUND;
  267.             return -1;
  268.         }
  269.     } else {
  270.         if ((offset + bufsize) > bp->blksize) {
  271.             BEPRINT;
  272.             errno = BEBOUND;
  273.             return -1;
  274.         }
  275.     }
  276. #endif
  277.  
  278. #if HOST == UNIX
  279.     /* read from file into buffer */
  280.     if (bn == 0) {            /* header */
  281.         pos = 0;
  282.     } else {            /* block */
  283.         pos = bp->hdrsize + (bn - 1) * bp->blksize;
  284.     }
  285.     pos += offset;
  286.     if (lseek(bp->fd.ifd, pos, SEEK_SET) == -1) {
  287.         BEPRINT;
  288.         return -1;
  289.     }
  290.     nr = read(bp->fd.ifd, (char *)buf, (unsigned)bufsize);
  291.     if (nr == -1) {
  292.         BEPRINT;
  293.         return -1;
  294.     }
  295.     if (nr != bufsize) {
  296.         BEPRINT;
  297.         errno = BEEOF;
  298.         return -1;
  299.     }
  300. #elif HOST == MSDOS
  301.     /* read from file into buffer */
  302.     if (bn == 0) {            /* header */
  303.         pos = 0;
  304.     } else {            /* block */
  305.         pos = bp->hdrsize + (bn - 1) * bp->blksize;
  306.     }
  307.     pos += offset;
  308.     if (lseek(bp->fd.ifd, pos, SEEK_SET) == -1) {
  309.         BEPRINT;
  310.         return -1;
  311.     }
  312.     nr = read(bp->fd.ifd, buf, (unsigned)bufsize);
  313.     if (nr == -1) {
  314.         BEPRINT;
  315.         return -1;
  316.     }
  317.     if (nr != bufsize) {
  318.         BEPRINT;
  319.         errno = BEEOF;
  320.         return -1;
  321.     }
  322. #endif
  323.  
  324.     errno = 0;
  325.     return 0;
  326. }
  327.  
  328. /*man---------------------------------------------------------------------------
  329. NAME
  330.      b_uopen - unbuffered open block file
  331.  
  332. SYNOPSIS
  333.      #include "blkio_.h"
  334.  
  335.      int b_uopen(bp, filename, type)
  336.      BLKFILE *bp;
  337.      const char *filename;
  338.      const char *type;
  339.  
  340. DESCRIPTION
  341.      The b_uopen function opens the physical file associated with the
  342.      BLKFILE pointer bp.
  343.  
  344.      b_uopen will fail if one or more of the following is true:
  345.  
  346.      [EINVAL]       bp is not a valid BLKFILE pointer.
  347.      [EINVAL]       filename or type is the NULL pointer.
  348.  
  349. SEE ALSO
  350.      b_uclose.
  351.  
  352. DIAGNOSTICS
  353.      Upon successful completion, a value of 0 is returned.  Otherwise,
  354.      a value of -1 is returned, and errno set to indicate the error.
  355.  
  356. ------------------------------------------------------------------------------*/
  357. int b_uopen(bp, filename, type)
  358. BLKFILE *bp;
  359. CONST char *filename;
  360. CONST char *type;
  361. {
  362. #if HOST == UNIX
  363.     int oflag = 0;
  364.     int fd = 0;
  365. #elif HOST == MSDOS
  366.     int oflag = 0;
  367.     int fd = 0;
  368. #endif
  369.  
  370. #ifdef DEBUG
  371.     /* validate arguments */
  372.     if (!b_valid(bp) || (filename == NULL) || (type == NULL)) {
  373.         BEPRINT;
  374.         errno = EINVAL;
  375.         return -1;
  376.     }
  377. #endif
  378.  
  379.     /* open file */
  380. #if HOST == UNIX
  381.     oflag = 0;
  382.     if (strcmp(type, BF_READ) == 0) {
  383.         oflag |= O_RDONLY;
  384.     } else if (strcmp(type, BF_RDWR) == 0) {
  385.         oflag |= O_RDWR;
  386.     } else if (strcmp(type, BF_CREATE) == 0) {
  387.         oflag |= O_RDWR | O_CREAT | O_EXCL;
  388.     } else if (strcmp(type, BF_CRTR) == 0) {
  389.         oflag |= O_RDWR | O_CREAT | O_TRUNC;
  390.     } else {
  391.         errno = EINVAL;
  392.         return -1;
  393.     }
  394.     fd = open(filename, oflag, MODE);
  395.     if (fd == -1) {
  396.         if ((errno != EACCES) && (errno != EEXIST) && (errno != ENOENT)) BEPRINT;
  397.         return -1;
  398.     }
  399.     bp->fd.ifd = fd;
  400. #elif HOST == MSDOS
  401.     oflag = O_BINARY;
  402.     if (strcmp(type, BF_READ) == 0) {
  403.         oflag |= O_RDONLY;
  404.     } else if (strcmp(type, BF_RDWR) == 0) {
  405.         oflag |= O_RDWR;
  406.     } else if (strcmp(type, BF_CREATE) == 0) {
  407.         oflag |= O_RDWR | O_CREAT | O_EXCL;
  408.     } else if (strcmp(type, BF_CRTR) == 0) {
  409.         oflag |= O_RDWR | O_CREAT | O_TRUNC;
  410.     } else {
  411.         errno = EINVAL;
  412.         return -1;
  413.     }
  414.     fd = open(filename, oflag, (unsigned)MODE);
  415.     if (fd == -1) {
  416.         if ((errno != EACCES) && (errno != EEXIST) && (errno != ENOENT)) BEPRINT;
  417.         return -1;
  418.     }
  419.     bp->fd.ifd = fd;
  420. #endif
  421.  
  422.     errno = 0;
  423.     return 0;
  424. }
  425.  
  426. /*man---------------------------------------------------------------------------
  427. NAME
  428.      b_uputf - unbuffered put field to block file
  429.  
  430. SYNOPSIS
  431.      #include "blkio_.h"
  432.  
  433.      int b_uputf(bp, bn, offset, buf, bufsize)
  434.      BLKFILE *bp;
  435.      bpos_t bn;
  436.      size_t offset;
  437.      const void *buf;
  438.      size_t bufsize;
  439.  
  440. DESCRIPTION
  441.      The b_uputf function writes bufsize characters from the buffer
  442.      pointed to by buf to block number bn of the block file associated
  443.      with BLKFILE pointer bp.  A value of zero for bn indicates the
  444.      file header.  The write starts offset characters from the
  445.      beginning of the block.  The sum of offset bufsize must not
  446.      exceed the header size if bn is equal to zero, or the block size
  447.      if bn is not equal to zero.
  448.  
  449.      b_uputf will fail if one or more of the following is true:
  450.  
  451.      [EINVAL]       bp is not a valid BLKFILE pointer.
  452.      [EINVAL]       buf is the NULL pointer.
  453.      [EINVAL]       bufsize is less than 1.
  454.      [BEBOUND]      offset + bufsize extends beyond the block
  455.                     boundary.
  456.      [BEEOF]        Partial block being written and block bn
  457.                     is past the end of file.
  458.      [BEEOF]        Complete block being written and block bn
  459.                     is more than 1 past the end of file.
  460.      [BENOPEN]      bp is not open for writing.
  461.  
  462. SEE ALSO
  463.      b_ugetf.
  464.  
  465. DIAGNOSTICS
  466.      Upon successful completion, a value of 0 is returned.  Otherwise,
  467.      a value of -1 is returned, and errno set to indicate the error.
  468.  
  469. ------------------------------------------------------------------------------*/
  470. int b_uputf(bp, bn, offset, buf, bufsize)
  471. BLKFILE *bp;
  472. bpos_t bn;
  473. size_t offset;
  474. CONST void *buf;
  475. size_t bufsize;
  476. {
  477. #if HOST == UNIX
  478.     long pos = 0;
  479.     int nw = 0;
  480. #elif HOST == MSDOS
  481.     long pos = 0;
  482.     int nw = 0;
  483. #endif
  484.  
  485. #ifdef DEBUG
  486.     /* validate arguments */
  487.     if (!b_valid(bp) || (buf == NULL) || (bufsize < 1)) {
  488.         BEPRINT;
  489.         errno = EINVAL;
  490.         return -1;
  491.     }
  492.  
  493.     /* check if not open */
  494.     if (!(bp->flags & BIOWRITE)) {
  495.         BEPRINT;
  496.         errno = BENOPEN;
  497.         return -1;
  498.     }
  499.  
  500.     /* check if block boundary is crossed */
  501.     if (bn == 0) {
  502.         if ((offset + bufsize) > bp->hdrsize) {
  503.             BEPRINT;
  504.             errno = BEBOUND;
  505.             return -1;
  506.         }
  507.     } else {
  508.         if ((offset + bufsize) > bp->blksize) {
  509.             BEPRINT;
  510.             errno = BEBOUND;
  511.             return -1;
  512.         }
  513.     }
  514. #endif
  515.  
  516. #if HOST == UNIX || HOST == MSDOS
  517.     /* write buffer to file */
  518.     if (bn == 0) {            /* header */
  519.         pos = 0;
  520.     } else {            /* block */
  521.         pos = bp->hdrsize + (bn - 1) * bp->blksize;
  522.     }
  523.     pos += offset;
  524.     if (lseek(bp->fd.ifd, pos, SEEK_SET) == -1) {
  525.         BEPRINT;
  526.         return -1;
  527.     }
  528.     nw = write(bp->fd.ifd, (char *)buf, (unsigned)bufsize);
  529.     if (nw == -1) {
  530.         BEPRINT;
  531.         return -1;
  532.     }
  533.     if (nw != bufsize) {
  534.         BEPRINT;
  535.         errno = BEPANIC;
  536.         return -1;
  537.     }
  538. #elif HOST == MSDOS
  539.     /* write buffer to file */
  540.     if (bn == 0) {            /* header */
  541.         pos = 0;
  542.     } else {            /* block */
  543.         pos = bp->hdrsize + (bn - 1) * bp->blksize;
  544.     }
  545.     pos += offset;
  546.     if (lseek(bp->fd.ifd, pos, SEEK_SET) == -1) {
  547.         BEPRINT;
  548.         return -1;
  549.     }
  550.     nw = write(bp->fd.ifd, buf, (unsigned)bufsize);
  551.     if (nw == -1) {
  552.         BEPRINT;
  553.         return -1;
  554.     }
  555.     if (nw != bufsize) {
  556.         BEPRINT;
  557.         errno = BEPANIC;
  558.         return -1;
  559.     }
  560. #endif
  561.  
  562.     errno = 0;
  563.     return 0;
  564. }
  565.